package com.jobson.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateful;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.jobson.model.Address;
import com.jobson.model.User;

/**
 * Backing bean for Address entities.
 * <p>
 * This class provides CRUD functionality for all Address entities. It focuses
 * purely on Java EE 6 standards (e.g. <tt>&#64;ConversationScoped</tt> for
 * state management, <tt>PersistenceContext</tt> for persistence,
 * <tt>CriteriaBuilder</tt> for searches) rather than introducing a CRUD
 * framework or custom base class.
 */

@Named
@Stateful
@ConversationScoped
public class AddressBean implements Serializable {

	private static final long serialVersionUID = 11L;

	private Address address;

	public Address getAddress() {
		return address;
	}

	@PersistenceContext(type = PersistenceContextType.EXTENDED)
	private EntityManager entityManager;

	// *********************************** ***********************************MY
	// Code starts here ***********************************
	// ***********************************">

	public Address findById() {

		Integer id = 1;
		return entityManager.find(Address.class, id);
	}

	public String save(Address aAddress) throws Exception {
		try {
			entityManager.persist(aAddress);
			return "search?faces-redirect=true";
			// return true;
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

	public Boolean update(Address aAddress) throws Exception {
		try {
			entityManager.merge(aAddress);
			return true;
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

	public Boolean delete(Address aAddress) throws Exception {
		try {
			entityManager.remove(aAddress);
			entityManager.flush();
			return true;
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

	public List<String> getSearchList(Address aAddress) {

		CriteriaBuilder builder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Address> query = builder.createQuery(Address.class);
		Root<Address> root = query.from(Address.class);
		List<String> searchList = new ArrayList<String>();
		List<Predicate> predicatesList = new ArrayList<Predicate>();

		String street = aAddress.getStreet();
		String additional = aAddress.getAdditional();
		String city = aAddress.getCity();
		String pin = aAddress.getPin();
		String district = aAddress.getDistrict();
		String state = aAddress.getState();
		String country = aAddress.getCountry();

		if (street != null && !"".equals(street)) {
			predicatesList.add(builder.like(root.<String> get("street"),
					additional + '%'));
		}

		else if (additional != null && !"".equals(additional)) {
			predicatesList.add(builder.like(root.<String> get("additional"),
					additional + '%'));
		}

		else if (city != null && !"".equals(city)) {
			predicatesList.add(builder.like(root.<String> get("city"),
					city + '%'));
		}

		else if (pin != null && !"".equals(pin)) {
			predicatesList
					.add(builder.like(root.<String> get("pin"), pin + '%'));
		}

		else if (district != null && !"".equals(district)) {
			predicatesList.add(builder.like(root.<String> get("district"),
					pin + '%'));
		} else if (country != null && !"".equals(country)) {
			predicatesList.add(builder.like(root.<String> get("country"),
					pin + '%'));
		} else if (state != null && !"".equals(state)) {
			predicatesList.add(builder.like(root.<String> get("state"),
					pin + '%'));
		}

		return null;
	}

	private void arrayBuilder(List<Object[]> aValues) {
		List<String> array = new ArrayList<String>();

		for (Object[] values : aValues) {
			array.add((String) values[0]);
		}
	}

	// *********************************** ***********************************
	// MY Code ends here ***********************************
	// ***********************************">

	private Predicate[] getSearchPredicates(Root<Address> root) {

		CriteriaBuilder builder = entityManager.getCriteriaBuilder();
		List<Predicate> predicatesList = new ArrayList<Predicate>();

		User user = address.getUser();
		if (user != null) {
			predicatesList.add(builder.equal(root.get("user"), user));
		}
		String street = address.getStreet();
		if (street != null && !"".equals(street)) {
			predicatesList.add(builder.like(root.<String> get("street"),
					street + '%'));
		}
		String additional = address.getAdditional();
		if (additional != null && !"".equals(additional)) {
			predicatesList.add(builder.like(root.<String> get("additional"),
					additional + '%'));
		}
		String city = address.getCity();
		if (city != null && !"".equals(city)) {
			predicatesList.add(builder.like(root.<String> get("city"),
					city + '%'));
		}
		String pin = address.getPin();
		if (pin != null && !"".equals(pin)) {
			predicatesList
					.add(builder.like(root.<String> get("pin"), pin + '%'));
		}

		return predicatesList.toArray(new Predicate[predicatesList.size()]);
	}

	/*
	 * Support adding children to bidirectional, one-to-many tables
	 */

	private Address add = new Address();

	public Address getAdd() {
		Address fr = new Address();
		fr.setCity("ch");
		getSearchList(fr);
		return add;
	}

	public Address getAdded() {
		Address added = add;
		add = new Address();
		return added;
	}
}